﻿// Type: JetBrains.Application.License.LicenseData
// Assembly: JetBrains.Platform.ReSharper.Shell, Version=6.0.2154.57, Culture=neutral, PublicKeyToken=1010a0d8d6380325
// Assembly location: D:\installed\JetBrains\ReSharper\v6.0\Bin\JetBrains.Platform.ReSharper.Shell.dll

using JetBrains.Annotations;
using JetBrains.Application;
using JetBrains.Util;
using JetBrains.Util.DataStructures;
using System;
using System.IO;

namespace JetBrains.Application.License
{
  public class LicenseData : IEquatable<LicenseData>
  {
    private DateTime? myExpirationDate = new DateTime?();
    private DateTime? myGenerationDate = new DateTime?();
    private LicenseType? myLicenseType = new LicenseType?();
    private int? myProductVersion = new int?();
    private int? myCustomerId = new int?();
    private int? myEditionCode = new int?();
    private const string LICENSE = "License";
    private const string USERNAME = "Username";
    private const string COMPANY = "Company";
    private const string USER_NAME = "User Name";
    private const string LICENSE_KEY = "License Key";
    private readonly string myPublicKey;
    private string myLicenseKey;
    private string myUserName;
    private string myCompanyName;
    private readonly LicenseData.AcceptLicenseDelegate myAcceptLicenseDelegate;
    private LicenseCheckResult myLicenseCheckResult;

    public LicenseType LicenseType
    {
      get
      {
        if (!this.myLicenseType.HasValue)
          this.CheckValidity();
        Logger.Assert(this.myLicenseType.HasValue, "myLicenseType != null");
        return this.myLicenseType.Value;
      }
    }

    public DateTime GenerationDate
    {
      get
      {
        if (!this.myGenerationDate.HasValue)
          this.CheckValidity();
        Logger.Assert(this.myGenerationDate.HasValue, "myGenerationDate != null");
        return this.myGenerationDate.Value;
      }
    }

    public DateTime ExpirationDate
    {
      get
      {
        if (!this.myExpirationDate.HasValue)
          this.CheckValidity();
        Logger.Assert(this.myExpirationDate.HasValue, "myExpirationDate != null");
        return this.myExpirationDate.Value;
      }
    }

    public int ProductVersion
    {
      get
      {
        if (!this.myProductVersion.HasValue)
          this.CheckValidity();
        Logger.Assert(this.myProductVersion.HasValue, "myProductVersion != null");
        return this.myProductVersion.Value;
      }
    }

    [NotNull]
    public Version ProductVersionAsVersion
    {
      get
      {
        if (!this.myProductVersion.HasValue)
          this.CheckValidity();
        return new Version(this.ProductVersion / 1000, this.ProductVersion % 1000);
      }
    }

    public int CustomerId
    {
      get
      {
        if (!this.myCustomerId.HasValue)
          this.CheckValidity();
        Logger.Assert(this.myCustomerId.HasValue, "myCustomerId != null");
        return this.myCustomerId.Value;
      }
    }

    public int EditionCode
    {
      get
      {
        if (!this.myEditionCode.HasValue)
          this.CheckValidity();
        Logger.Assert(this.myEditionCode.HasValue, "myEditionCode != null");
        return this.myEditionCode.Value;
      }
      set
      {
        this.myEditionCode = new int?(value);
      }
    }

    public bool IsEndless
    {
      get
      {
        return this.ExpirationDate == DateTime.MaxValue;
      }
    }

    public string LicenseKey
    {
      get
      {
        return this.myLicenseKey;
      }
      set
      {
        this.myLicenseKey = value;
      }
    }

    public string UserName
    {
      get
      {
        return this.myUserName;
      }
      set
      {
        this.myUserName = value;
      }
    }

    public string CompanyName
    {
      get
      {
        return this.myCompanyName;
      }
      set
      {
        this.myCompanyName = value;
      }
    }

    public string PublicKey
    {
      get
      {
        return this.myPublicKey;
      }
    }

    public LicenseData(string publicKey, string licenseKey, string userName, string companyName, [CanBeNull] LicenseData.AcceptLicenseDelegate acceptLicenseDelegate)
    {
      this.myPublicKey = publicKey;
      this.myLicenseKey = licenseKey;
      this.myUserName = userName;
      this.myCompanyName = companyName;
      this.myAcceptLicenseDelegate = acceptLicenseDelegate;
    }

    public LicenseData(string publicKey, string licenseKey, string userName, string companyName)
      : this(publicKey, licenseKey, userName, companyName, (LicenseData.AcceptLicenseDelegate) null)
    {
    }

    public bool Equals(LicenseData licenseData)
    {
      if (licenseData == null || !object.Equals((object) this.myPublicKey, (object) licenseData.myPublicKey) || (!object.Equals((object) this.myLicenseKey, (object) licenseData.myLicenseKey) || !object.Equals((object) this.myUserName, (object) licenseData.myUserName)) || !object.Equals((object) this.myCompanyName, (object) licenseData.myCompanyName))
        return false;
      else
        return true;
    }

    public override bool Equals(object obj)
    {
      if (this == obj)
        return true;
      else
        return this.Equals(obj as LicenseData);
    }

    public override int GetHashCode()
    {
      return 29 * (29 * (29 * this.myPublicKey.GetHashCode() + this.myLicenseKey.GetHashCode()) + this.myUserName.GetHashCode()) + this.myCompanyName.GetHashCode();
    }

    [CanBeNull]
    public static LicenseData GetLicenseDataFromUserSettings(string publicKey, LicenseData.AcceptLicenseDelegate acceptor, ISettingsTable settings)
    {
      string encryptedString = EncryptionUtil.GetEncryptedString(settings, "License");
      string string1 = settings.GetString("Username");
      string string2 = settings.GetString("Company");
      if (string.IsNullOrEmpty(encryptedString) || string.IsNullOrEmpty(string1))
        return (LicenseData) null;
      else
        return new LicenseData(publicKey, encryptedString, string1, string2 ?? string.Empty, acceptor);
    }

    public static FileSystemPath GetEvaluationLicensePath(FileSystemPath installDir)
    {
      try
      {
        return installDir.Combine("EvaluationLicense.txt");
      }
      catch (Exception ex)
      {
        Logger.LogException(ex);
        return FileSystemPath.Empty;
      }
    }

    public static LicenseData GetEvaluationLicenseDataFromFile(string publicKey, LicenseData.AcceptLicenseDelegate acceptor, FileSystemPath installDir)
    {
      try
      {
        FileSystemPath evaluationLicensePath = LicenseData.GetEvaluationLicensePath(installDir);
        if (!evaluationLicensePath.ExistsFile)
          return (LicenseData) null;
        string userName = (string) null;
        string licenseKey = (string) null;
        try
        {
          FileSystemPathEx.ReadTextStream(evaluationLicensePath, (Action<StreamReader>) (sr =>
          {
            while (true)
            {
              string[] local_1;
              do
              {
                string local_0 = sr.ReadLine();
                if (local_0 == null)
                  return;
                local_1 = local_0.Split(new char[1]
                {
                  ':'
                });
              }
              while (local_1.Length != 2);
              switch (local_1[0])
              {
                case "User Name":
                  local_1[1].Trim();
                  continue;
                case "License Key":
                  local_1[1].Trim();
                  continue;
                default:
                  continue;
              }
            }
          }));
        }
        catch
        {
        }
        if (userName != null && licenseKey != null)
          return new LicenseData(publicKey, licenseKey, userName, "", acceptor);
        else
          return (LicenseData) null;
      }
      catch
      {
        return (LicenseData) null;
      }
    }

    public void SaveToUserSettings(ISettingsTable settings)
    {
      EncryptionUtil.SetEncryptedString(settings, "License", this.LicenseKey);
      settings.SetString("Username", this.UserName);
    }

    public LicenseCheckResult Check()
    {
      if (this.myLicenseCheckResult != null)
        return this.myLicenseCheckResult;
      LicenseCheckResult licenseCheckResult = this.CheckValidity();
      if (licenseCheckResult == LicenseCheckResult.LICENSE_VALID && this.myAcceptLicenseDelegate != null)
        licenseCheckResult = this.myAcceptLicenseDelegate(this);
      this.myLicenseCheckResult = licenseCheckResult;
      return this.myLicenseCheckResult;
    }

    private LicenseCheckResult CheckValidity()
    {
      try
      {
        int result = -1;
        string license = this.LicenseKey;
        int length = license.IndexOf('-');
        if (length >= 0 && length + 1 < license.Length && int.TryParse(license.Substring(0, length), out result))
          license = license.Substring(length + 1);
        LicenseChecker licenseChecker = new LicenseChecker(this.PublicKey, this.UserName, this.CompanyName, license);
        if (!licenseChecker.IsChecksumOK)
        {
          this.myExpirationDate = new DateTime?(DateTime.MinValue);
          this.myGenerationDate = new DateTime?(DateTime.MinValue);
          this.myProductVersion = new int?(0);
          this.myCustomerId = new int?(0);
          this.myEditionCode = new int?(0);
          this.myLicenseType = new LicenseType?(LicenseType.INVALID);
          return LicenseCheckResult.LICENSE_INVALID;
        }
        else
        {
          this.myExpirationDate = new DateTime?(licenseChecker.ExpirationDate);
          this.myGenerationDate = new DateTime?(licenseChecker.GenerationDate);
          this.myLicenseType = new LicenseType?((LicenseType) licenseChecker.Type);
          this.myProductVersion = new int?(licenseChecker.ProductVersion);
          this.myCustomerId = new int?(licenseChecker.CustomerId);
          this.myEditionCode = new int?(licenseChecker.Edition);
          if (result >= 0 && licenseChecker.CustomerId != result)
            return LicenseCheckResult.LICENSE_INVALID;
          LicenseType? nullable = this.myLicenseType;
          if ((nullable.GetValueOrDefault() != LicenseType.FLOATING ? 0 : (nullable.HasValue ? 1 : 0)) != 0)
            return new LicenseCheckResult("Floating license can be used with license server only", new object[0]);
          if (licenseChecker.ExpirationDate > DateTime.Now.Date)
            return LicenseCheckResult.LICENSE_VALID;
          else
            return LicenseCheckResult.LICENSE_EXPIRED;
        }
      }
      catch
      {
        this.myExpirationDate = new DateTime?(DateTime.MinValue);
        this.myGenerationDate = new DateTime?(DateTime.MinValue);
        this.myLicenseType = new LicenseType?(LicenseType.INVALID);
        this.myProductVersion = new int?(0);
        this.myCustomerId = new int?(0);
        this.myEditionCode = new int?(0);
        return LicenseCheckResult.LICENSE_INVALID;
      }
    }

    public ProductEdition GetEdition([NotNull] ILicenseSupport licenseSupport, IApplicationDescriptor descriptor)
    {
      return licenseSupport.DecodeProductEdition(this.EditionCode, descriptor);
    }

    public delegate LicenseCheckResult AcceptLicenseDelegate(LicenseData data);
  }
}
